package com.wds.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wds.common.utils.BeanCopyUtils;
import com.wds.domain.JsonResult;
import com.wds.domain.entity.Comment;
import com.wds.domain.entity.User;
import com.wds.domain.type.SystemConstants;
import com.wds.domain.vo.CommentVo;
import com.wds.domain.vo.PageVo;
import com.wds.exception.CustomException;
import com.wds.mapper.CommentMapper;
import com.wds.service.CommentService;
import com.wds.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 评论表(Comment)表服务实现类
 *
 * @author wds
 * @since 2022-10-21 15:50:18
 */
@Service("commentService")
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    @Autowired
    private UserService userService;

    /**
     * 分页查询对应文章的根评论
     */
    @Override
    public JsonResult<Object> getCommentList(Long articleId, Integer pageNum, Integer pageSize) {
        if (articleId == null || pageNum == null || pageSize == null) {
            throw new CustomException("参数有误，请检查参数");
        }
        PageVo pageVo = this.getComment(articleId, SystemConstants.CONTENT_TYPE_ARTICLE, pageNum, pageSize);
        return JsonResult.ok(pageVo);
    }

    /**
     * 获取友链的品论
     */
    @Override
    public JsonResult<Object> getLinkCommentList(Long articleId, Integer pageNum, Integer pageSize) {
        if (pageNum == null || pageSize == null) {
            throw new CustomException("参数有误，请检查参数");
        }
        PageVo pageVo = this.getComment(articleId, SystemConstants.CONTENT_TYPE_LINK, pageNum, pageSize);
        return JsonResult.ok(pageVo);
    }

    /**
     * 发表评论
     * 1. 根评论 2.回复评论 3.友链评论
     */
    @Override
    public JsonResult<Object> addComment(Comment comment) {
        save(comment);
        return JsonResult.ok();
    }


    /**
     * 查询评论方法  查询对应文章或者子链页面下的评论
     *
     * @param articleId 二选一 查询子链品论传值null
     * @param type      二选一 查询文章id穿null
     * @param pageNum   必须
     * @param pageSize  必须
     * @return PageVo 分页对象
     */
    private PageVo getComment(Long articleId, Character type, Integer pageNum, Integer pageSize) {

        // 查询安全限制
        if (pageSize > 100) {
            pageSize = 10;
        }


        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
        //类型 1友链 2文章
        queryWrapper.eq(Comment::getType, type);
        //类型对应的文章Id
        queryWrapper.eq(Comment::getArticleId, articleId);

        // 目标评论 id 为 -1
        queryWrapper.eq(Comment::getRootId, -1);
        queryWrapper.orderByDesc(Comment::getCreateTime);

        Page<Comment> page = new Page<>(pageNum, pageSize);
        Page<Comment> resultPage = page(page, queryWrapper);

        // copy vo
        List<CommentVo> voList = BeanCopyUtils.copyList(resultPage.getRecords(), CommentVo.class);

        //封装评论用户的昵称，该评论的子评论，子评论用户的昵称
        List<CommentVo> result = voList.stream().peek((vo) -> {
            //查询评论 nick
            Long toCommentUserId = vo.getCreateBy();
            User toCommentUser = userService.getById(toCommentUserId);
            vo.setUsername(toCommentUser.getNickName());

            // 查询子评论
            Long rootId = vo.getId();
            LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Comment::getRootId, rootId);
            wrapper.orderByDesc(Comment::getCreateTime);

            List<CommentVo> children = BeanCopyUtils.copyList(list(wrapper), CommentVo.class);

            // 封装子评论 Nick
            children = children.stream().peek((commentVo) -> {
                //子评论 昵称
                User commentUser = userService.getById(commentVo.getCreateBy());
                commentVo.setUsername(commentUser.getNickName());
                //父评论的昵称
                commentVo.setToCommentUserName(vo.getUsername());
            }).collect(Collectors.toList());

            vo.setChildren(children);
        }).collect(Collectors.toList());


        return new PageVo(result, resultPage.getTotal());
    }

}

